﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Microsoft.Popfly.GameCreator.GameEngine.Events
{
    public class CollisionListener : EventListener
    {
        public enum CollisionEventType { ONCOLLIDE, COLLIDE };
        public CollisionEventType CollisionEvent;
        public CollisionEventArgsFilter ArgsFilter { get; private set; }
        public CollisionClassWithListener[] CollisionClasses { get; private set; }

        public void Raise(BehaviorOwner sender, CollisionEventArgs args)
        {
            if (!QueuedForRemoval)
            {
                if (Filter == null || Filter.CheckFilter())
                {
                    if (ArgsFilter.CheckArgs(args))
                    {
                        if (AudioUrl != null)
                        {
                            m_game.PlayAudio(AudioUrl);
                        }
                        Behavior.Invoke(sender, args);
                    }
                }
            }
        }

        public CollisionListener(
            Game game, 
            BehaviorOwner owner, 
            Filter filter, 
            Behaviors.IBehavior behavior, 
            string behaviorName, 
            string audioUrl, 
            CollisionEventArgsFilter argsFilter, 
            CollisionClassWithListener collisionClass1, 
            CollisionClassWithListener collisionClass2
            ) : base(game, owner, filter, behavior, behaviorName, audioUrl)
        {
            ArgsFilter = argsFilter;
            CollisionClasses = new CollisionClassWithListener[2];
            CollisionClasses[0] = collisionClass1;
            CollisionClasses[1] = collisionClass2;
        }

        public CollisionListener(Game game, BehaviorOwner owner, Data.BehaviorInfo behaviorInfo) : base(game, owner, behaviorInfo)
        {
            Type eventType = behaviorInfo.Event.GetType();
            if (eventType != typeof(Data.CollisionEventInfo))
            {
                throw new ArgumentException(
                    Utils.ErrorMessagePrefix +
                    "CollisionListener only takes CollisionEventInfos in its constructor.  " +
                    "behaviorInfo.Event was of type '" + eventType.ToString() + "'."
                    );
            }

            Data.CollisionEventInfo collisionEventInfo = (Data.CollisionEventInfo)behaviorInfo.Event;

            switch (collisionEventInfo.CollisionType)
            {
                case "CollisionStart" :
                    CollisionEvent = CollisionEventType.ONCOLLIDE;
                    break;
                case "Collision" :
                    CollisionEvent = CollisionEventType.COLLIDE;
                    break;
                default :
                    throw new ArgumentException(
                        Utils.ErrorMessagePrefix +
                        "CollisionListener does not know how to handle a CollisionType of '" +
                        collisionEventInfo.CollisionType + "'."
                        );
            }
            CollisionClasses = new CollisionClassWithListener[2];
            CollisionClasses[0] = new CollisionClassWithListener(
                this, 
                owner, 
                collisionEventInfo.Includes, 
                collisionEventInfo.SubType);

            CollisionClasses[1] = new CollisionClassWithListener(
                this, 
                owner, 
                collisionEventInfo.Includes2, 
                collisionEventInfo.SubType2);

            ArgsFilter = new CollisionEventArgsFilter(CollisionClasses, collisionEventInfo);
        } // end method
    } // end class
}// end namespace
